#pragma once

#include <openssl/sha.h>
#include "../base/types.h"


OPEN_JLIB_NS


template<s32 V = 1>
struct SHA {
};


template<>
struct SHA<1> {

  constexpr static uwl hash_size () {
    return 20;
  }

  inline static uwl hash (void *dst, const void *src, uwl src_size) noexcept {
    ::SHA1((const u8*)src, src_size, (u8*)dst);
    return 20;
  }
};


template<>
struct SHA<224> {

  constexpr static uwl hash_size () {
    return 28;
  }

  inline static uwl hash (void *dst, const void *src, uwl src_size) noexcept {
    ::SHA224((const u8*)src, src_size, (u8*)dst);
    return 28;
  }

};


template<>
struct SHA<256> {

  constexpr static uwl hash_size () {
    return 32;
  }

  inline static uwl hash (void *dst, const void *src, uwl src_size) noexcept {
    ::SHA256((const u8*)src, src_size, (u8*)dst);
    return 32;
  }

};


template<>
struct SHA<384> {

  constexpr static uwl hash_size () {
    return 48;
  }

  inline static uwl hash (void *dst, const void *src, uwl src_size) noexcept {
    ::SHA384((const u8*)src, src_size, (u8*)dst);
    return 48;
  }

};


template<>
struct SHA<512> {

  constexpr static uwl hash_size () {
    return 64;
  }

  inline static uwl hash (void *dst, const void *src, uwl src_size) noexcept {
    ::SHA512((const u8*)src, src_size, (u8*)dst);
    return 64;
  }

};


CLOSE_JLIB_NS
